package com.agadmin.config;

import ch.qos.logback.core.model.processor.ModelHandlerException;
import com.auth0.jwt.interfaces.DecodedJWT;

import com.agadmin.common.JWTUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.filter.OncePerRequestFilter;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;

import java.io.IOException;
import java.util.Optional;

@Slf4j
@Component
public class JWTAuthorizeFilter extends OncePerRequestFilter {

    @Autowired
    @Qualifier("handlerExceptionResolver")
    HandlerExceptionResolver resolver;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;


    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {


        String token = request.getHeader("Authorization");

        if (token != null) {
            boolean verify = JWTUtil.verify(token);
            if (!verify) {
                resolver.resolveException(request, response,
                        null, new IllegalArgumentException("TOKEN校验错误"));
                return;
            }

            boolean jwtExpired = JWTUtil.isJwtExpired(token);
            DecodedJWT jwt = JWTUtil.parseToken(token);
            if (jwtExpired) {
                if (jwt != null) {
                    CustomUser user = JWTUtil.toUser(jwt);
                    String userId = user.getSysUser().getId();

                    Long expire = redisTemplate.opsForValue().getOperations().getExpire(userId);

                    if (expire != null && expire > 0) {
                        log.info("重新生成token");
                        String newToken = JWTUtil.createToken(user, userId, user.getUsername());
                        response.setHeader("refresh_token","true");
                        response.setHeader("token",newToken);

                    }
                } else {
                    resolver.resolveException(request, response,
                            null, new IllegalArgumentException("TOKEN已过期,请重新登录"));
                    return;
                }
            }


        }

        log.info("token--==" + token);

        DecodedJWT jwt = JWTUtil.parseToken(token);

        if (jwt != null) {
            CustomUser user = JWTUtil.toUser(jwt);
            UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user,
                    null,
                    user.getAuthorities());
            auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(auth);
            request.setAttribute("userId", user.getSysUser().getId());

        }

        filterChain.doFilter(request, response);
    }
}
